﻿using Cofe.Core;
using Cofe.Core.Dynamic;
using Cofe.Core.Property;
using Cofe.IO;
using Cofe.IO.Interfaces;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace Cofe.IO.Implements
{
    [Export(typeof(ICofeService))]
    [ServicePriority(ServicePriorityAttribute.DefaultPriority_COFEIO)]
    public class FSIInterfaceProvider : IDynamicPropertyInterfaceProvider
    {
        public bool CanCastAs<T>(IPropertyHost input) where T : IDynamicInterface<IPropertyHost>
        {
            if (typeof(T) == typeof(IFileSystemInfo))
                return input.SupportedDefinitions.Contains(PropertyDefinitions.FSIPropDefinitions,
                    PropertyDefinitionComparer.CompareCategory);

            if (typeof(T) == typeof(IFileInfo))
                return input.SupportedDefinitions.Contains(PropertyDefinitions.FIPropDefinitions,
                    PropertyDefinitionComparer.CompareCategory);

            if (typeof(T) == typeof(IDirectoryInfo))
                return input.SupportedDefinitions.Contains(PropertyDefinitions.DIPropDefinitions,
                    PropertyDefinitionComparer.CompareCategory);

            //if (input.PrimaryPropertyProvider is IFSIPropertyProvider)
            //{
            //    if (typeof(T) == typeof(IFileSystemInfo))
            //        return true;
            //    FileAttributes fa = input.Behaviors.GetProperty(FileSystemInfoProperties.FileAttributes).ValueAs<FileAttributes>();
            //    if (fa.HasFlag(FileAttributes.Directory))
            //    {
            //        //Directory
            //        if (typeof(T) == typeof(IDirectoryInfo))
            //            return true;
            //    }
            //    else
            //    {
            //        //File
            //        if (typeof(T) == typeof(IFileInfo))
            //            return true;
            //    }

            //}
            return false;
        }

        public T CastAs<T>(IPropertyHost input) where T : IDynamicInterface<IPropertyHost>
        {
            if (CanCastAs<T>(input))
            {
                if (typeof(T) == typeof(IDirectoryInfo) || typeof(T) == typeof(ICofeDirectoryInfo))
                {
                    return (T)(IDirectoryInfo)new DirectoryInfo(input);
                }

                if (typeof(T) == typeof(IFileInfo) || typeof(T) == typeof(ICofeItemInfo))
                {
                    return (T)(IFileInfo)new FileInfo(input);
                }

                if (typeof(T) == typeof(IFileSystemInfo))
                {
                    FileAttributes fa = input.Behaviors.GetProperty(FileSystemInfoProperties.FileAttributes).ValueAs<FileAttributes>();
                    var returnDir = fa.HasFlag(FileAttributes.Directory);
                    if (returnDir)
                        return (T)(IDirectoryInfo)new DirectoryInfo(input);
                    else return (T)(IFileInfo)new FileInfo(input);
                }
            }
            throw new NotSupportedException();
        }

        public Type[] CastableInterfaces
        {
            get { return new Type[] { typeof(IFileSystemInfo), typeof(IFileInfo), typeof(IDirectoryInfo) }; }
        }


        public Type[] CastableContainers
        {
            get { return new Type[] { typeof(FileInfo), typeof(DirectoryInfo) }; }
        }
    }
}
